//
//  CNView.swift
//  Voice
//
//  Created by 卢逢卫 on 2024/3/11.
//

import Foundation

import UIKit

extension UIView {
    
    /// 初始化视图
        ///
        /// - Returns: 初始化后的视图
        public static func cn_initViewWith() -> Self {
            return self.init()
        }
    
    /// 可变参数函数
    ///
    /// eg:
    ///     self.view.cn_addSubViews(views: btn, imagView)
    ///
    public func cn_addSubViews(views: UIView...) {
        for view in views {
            self.addSubview(view)
        }
    }

    ///
    /// eg:
    ///     self.view.cn_removeSubviews()
    ///
    public func cn_removeSubviews() {
        for subview in self.subviews {
            subview.removeFromSuperview()
        }
    }

    ///
    ///
    ///
    public func cn_addTapGesture(target: AnyObject, action: Selector) {
        // 设置 isUserInteractionEnabled 属性为 true
        isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: target, action: action)
        self.addGestureRecognizer(tapGesture)
    }

    ///
    ///
    ///
    public func cn_addTapGesture(_ block: ((UIGestureRecognizer) -> Void)?) {
        // 设置 isUserInteractionEnabled 属性为 true
                isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
        if let block = block {
            objc_setAssociatedObject(self, &tapGestureBlockKey, block, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        self.addGestureRecognizer(tapGesture)
    }

    @objc private func handleTapGesture(_ gesture: UITapGestureRecognizer) {
        if let block = objc_getAssociatedObject(self, &tapGestureBlockKey) as? ((UIGestureRecognizer) -> Void) {
            block(gesture)
        }
    }

    ///
    ///
    ///
    public func cn_addLongGesture(_ block: ((UIGestureRecognizer) -> Void)?) {
        // 设置 isUserInteractionEnabled 属性为 true
                isUserInteractionEnabled = true
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
        if let block = block {
            objc_setAssociatedObject(self, &longPressGestureBlockKey, block, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        self.addGestureRecognizer(longPressGesture)
    }

    @objc private func handleLongPressGesture(_ gesture: UILongPressGestureRecognizer) {
        // 设置 isUserInteractionEnabled 属性为 true
                isUserInteractionEnabled = true
        if let block = objc_getAssociatedObject(self, &longPressGestureBlockKey) as? ((UIGestureRecognizer) -> Void) {
            block(gesture)
        }
    }

    ///
    ///
    ///
    public func cn_addSwipeGesture(direction: UISwipeGestureRecognizer.Direction, _ block: ((UIGestureRecognizer) -> Void)?) {
        // 设置 isUserInteractionEnabled 属性为 true
                isUserInteractionEnabled = true
        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeGesture(_:)))
        swipeGesture.direction = direction
        if let block = block {
            objc_setAssociatedObject(self, &swipeGestureBlockKey, block, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        self.addGestureRecognizer(swipeGesture)
    }

    @objc private func handleSwipeGesture(_ gesture: UISwipeGestureRecognizer) {
        if let block = objc_getAssociatedObject(self, &swipeGestureBlockKey) as? ((UIGestureRecognizer) -> Void) {
            block(gesture)
        }
    }

    ///
    ///
    ///
    public func cn_removeGestures() {
        if let gestures = self.gestureRecognizers {
            for gesture in gestures {
                self.removeGestureRecognizer(gesture)
            }
        }
    }

    ///
    ///
    ///
    public func cn_dismissKeyboard() {
        self.endEditing(true)
    }

    ///
    ///- Parameters:
    ///   - length: 线长
    ///   - spacing: 间隔
    ///   - color: 颜色
    public func cn_drawDashLine(length: Int, spacing: Int, color: UIColor) {
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = color.cgColor
        shapeLayer.lineWidth = self.bounds.height
        shapeLayer.lineJoin = .round
        shapeLayer.lineDashPattern = [NSNumber(value: length), NSNumber(value: spacing)]
        let path = CGMutablePath()
        path.move(to: CGPoint(x: 0, y: self.bounds.height / 2))
        path.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height / 2))
        shapeLayer.path = path
        self.layer.addSublayer(shapeLayer)
    }

    ///
    ///
    ///
    public func cn_snapshotImage() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
        defer {
            UIGraphicsEndImageContext()
        }
        if let context = UIGraphicsGetCurrentContext() {
            self.layer.render(in: context)
            let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
            return snapshotImage
        }
        return nil
    }
}

private var tapGestureBlockKey: UInt8 = 0
private var longPressGestureBlockKey: UInt8 = 0
private var swipeGestureBlockKey: UInt8 = 0



extension UIView {

    public enum GradientColorPoints {
        case left
        case leftTop
        case leftBottom
        case right
        case rightTop
        case rightBottom
        case top
        case bottom
    }

    func cn_setGradientColors(colors: [UIColor], startPoint: GradientColorPoints, endPoint: GradientColorPoints) {
//        let gradientLayer = CAGradientLayer()
        
        
        print(self.bounds)
        DispatchQueue.main.async {
            print(self.bounds)
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = colors.map { $0.cgColor }
            gradientLayer.startPoint = self.gradientPoint(for: startPoint, in: self.bounds.size)
            gradientLayer.endPoint = self.gradientPoint(for: endPoint, in: self.bounds.size)
            gradientLayer.frame = self.bounds
//            self.superview?.layer.insertSublayer(gradientLayer, below: self.layer)
            self.layer.insertSublayer(gradientLayer, at: 0)
        }
        
    }
        
        private func gradientPoint(for position: GradientColorPoints, in bounds: CGSize) -> CGPoint {
            switch position {
            case .left:
                return CGPoint(x: 0, y: 0.5)
            case .leftTop:
                return CGPoint(x: 0, y: 0)
            case .leftBottom:
                return CGPoint(x: 0, y: 1)
                
            case .right:
                return CGPoint(x: 1, y: 0.5)
            case .rightTop:
                return CGPoint(x: 1 , y: 0)
            case .rightBottom:
                return CGPoint(x: 1, y: 1)
            case .top:
                return CGPoint(x: 0.5, y: 0)
            case .bottom:
                return CGPoint(x: 0.5, y: 1)
            }
        }

    public func cn_blurry(withStyle style: UIBlurEffect.Style = .light) {
        let blurEffect = UIBlurEffect(style: style)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.frame = bounds
        addSubview(blurView)
    }

    public func cn_setShadow(color: UIColor, offset: CGSize, opacity: Float, radius: CGFloat) {
        layer.shadowColor = color.cgColor
        layer.shadowOffset = offset
        layer.shadowOpacity = opacity
        layer.shadowRadius = radius
    }

    public func cn_setAllCorners(radii: CGFloat = 0.0) {
        layer.cornerRadius = radii
        layer.masksToBounds = true
    }

    public func cn_setSomeCorners(corners_after: CACornerMask, corners_before: UIRectCorner, radii: CGFloat) {
        if #available(iOS 11.0, *) {
            layer.cornerRadius = radii
            layer.maskedCorners = corners_after
        } else {
            let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners_before, cornerRadii: CGSize(width: radii, height: radii))
            let maskLayer = CAShapeLayer()
            maskLayer.frame = bounds
            maskLayer.path = maskPath.cgPath
            layer.mask = maskLayer
        }
    }

    public func cn_setBorder(width: CGFloat, color: UIColor) {
        layer.borderWidth = width
        layer.borderColor = color.cgColor
    }
}


extension UIView {

    public func cn_peekAnimation() {
        let originalTransform = transform
        let scaledTransform = originalTransform.scaledBy(x: 1.1, y: 1.1)
        
        UIView.animate(withDuration: 0.1, animations: {
            self.transform = scaledTransform
        }) { (_) in
            UIView.animate(withDuration: 0.1, animations: {
                self.transform = originalTransform
            })
        }
    }

    public func cn_shakeAnimation() {
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: .linear)
        animation.duration = 0.6
        animation.values = [-10.0, 10.0, -10.0, 10.0, -5.0, 5.0, -2.5, 2.5, 0.0]
        layer.add(animation, forKey: "shakeAnimation")
    }

    public func cn_springAnimation(withDuration duration: TimeInterval, usingSpringWithDamping damping: CGFloat, animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil) {
        UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: 0, options: [], animations: {
            animations?()
        }, completion: { finished in
            completion?(finished)
        })
    }
}


extension UIView {
    /// 使用指定的背景颜色和圆角半径初始化视图
    ///
    /// - Parameters:
    ///   - background: 视图的背景颜色
    ///   - radii: 视图的圆角半径
    /// - Returns: 初始化后的视图
    public static func cn_initViewWith(background: UIColor, radii: CGFloat) -> Self {
        let view = self.init()
        view.backgroundColor = background
        view.layer.cornerRadius = radii
        view.layer.masksToBounds = true
        return view
    }
    
    /// 使用指定的圆角半径初始化视图
        ///
        /// - Parameter radii: 视图的圆角半径
        /// - Returns: 初始化后的视图
        public static func cn_initViewWith(radii: CGFloat) -> Self {
            let view = self.init()
            view.layer.cornerRadius = radii
            view.layer.masksToBounds = true
            return view
        }
    
    public static func cn_initViewWith(background: UIColor) -> Self {
           let view = self.init()
           view.backgroundColor = background
           return view
       }
}


extension UIView {
    var cn_height: CGFloat {
        get {
            return frame.size.height
        }
        set {
            var frame = self.frame
            frame.size.height = newValue
            self.frame = frame
        }
    }
    
    var cn_width: CGFloat {
        get {
            return frame.size.width
        }
        set {
            var frame = self.frame
            frame.size.width = newValue
            self.frame = frame
        }
    }
    
    var cn_size: CGSize {
            get {
                return frame.size
            }
            set {
                var frame = self.frame
                frame.size = newValue
                self.frame = frame
            }
        }
}
